package cn.topcodes.tcsf.app.web.controller.admin;

import cn.topcode.unicorn.utils.RenderUtil;
import cn.topcode.unicorn.utils.UuidUtil;
import cn.topcode.unicorn.utils.ValidationUtil;
import cn.topcodes.tcsf.admin.commons.api.controller.admin.AdminController;
import cn.topcodes.tcsf.admin.commons.api.domain.ApiResponseEntity;
import cn.topcodes.tcsf.admin.commons.api.security.ShiroUtil;
import cn.topcodes.tcsf.admin.domain.form.NestableSort;
import cn.topcodes.tcsf.app.domain.entity.HelpArticle;
import cn.topcodes.tcsf.app.domain.entity.HelpArticleCatalog;
import cn.topcodes.tcsf.app.domain.form.HelpArticleForm;
import cn.topcodes.tcsf.app.domain.vo.ActionMap;
import cn.topcodes.tcsf.app.domain.vo.HelpArticleVo;
import cn.topcodes.tcsf.app.domain.vo.UEditor;
import cn.topcodes.tcsf.app.domain.vo.UEditorImageUpload;
import cn.topcodes.tcsf.app.mapper.HelpArticleMapper;
import cn.topcodes.tcsf.app.service.HelpArticleCatalogService;
import cn.topcodes.tcsf.app.service.HelpArticleService;
import cn.topcodes.tcsf.app.service.impl.ConfigService;
import cn.topcodes.tcsf.app.web.controller.api.OtherApi;
import com.alibaba.fastjson.JSONObject;
import io.swagger.annotations.ApiParam;
import org.apache.commons.lang3.StringEscapeUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import tk.mybatis.mapper.entity.Example;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.*;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * HelpArticle管理控制器
 *
 * @author Yvan
 */
@Controller
@RequestMapping("/admin/helparticle")
public class HelpArticleController extends AdminController<HelpArticle, HelpArticleVo, HelpArticleForm> {

    @Autowired
    private ConfigService configService;

    @Autowired
    private HelpArticleService helpArticleService;

    @Autowired
    private HelpArticleCatalogService helpArticleCatalogService;

    @Autowired
    private HelpArticleMapper helpArticleMapper;

    @Override
    protected String getPageFolder() {
        return "app/admin/helparticle";
    }

    @RequestMapping("editor")
    public void editor(HttpServletResponse response,
                       HttpServletRequest request,
                       @RequestParam("action") String action) throws Exception {

        switch (action) {
            case ActionMap.CONFIG:
                loadConfig(response, request);
                break;
            case ActionMap.UPLOADIMAGE:
                ImageUpload(response, request, "cms-content-images");
                break;
            case ActionMap.UPLOADVIDEO:
                ImageUpload(response, request, "cms-content-video");
                break;
            default:
                break;
        }
    }

    @RequestMapping("articleSort")
    public String articleSort(Model model) {

        Example example = helpArticleService.buildExample();
        example.setOrderByClause(HelpArticle.FIELD_SORT + " asc");
        List<HelpArticle> all = helpArticleService.findAll(example);
        model.addAttribute("all", all);
        return this.getPageFolder() + "/articleSort";
    }

    @RequestMapping("save-sort")
    @ResponseBody
    public ApiResponseEntity saveSort(@RequestBody(required = true) List<NestableSort> sort) {

        helpArticleService.saveSort(sort);
        return ApiResponseEntity.buildOK();
    }

    @RequestMapping("articleList")
    @ResponseBody
    public ApiResponseEntity articleList() {

        List<HelpArticleCatalog> catalogServiceAll = helpArticleCatalogService.findAll();
        List<HelpArticle> articleServiceAll = helpArticleService.findAll();
        catalogServiceAll.addAll(article2ArticleCatalog(articleServiceAll));
        return ApiResponseEntity.buildOK().setBody(catalogServiceAll);
    }

    private List<HelpArticleCatalog> article2ArticleCatalog(List<HelpArticle> helpArticles) {

        List<HelpArticleCatalog> helpArticleCatalogs = new ArrayList<>();
        if (null != helpArticles && !helpArticles.isEmpty()) {
            for (HelpArticle helpArticle : helpArticles) {
                HelpArticleCatalog helpArticleCatalog = new HelpArticleCatalog();
                helpArticleCatalog.setName(helpArticle.getTitle());
                helpArticleCatalog.setId(helpArticle.getId());
                helpArticleCatalog.setParentId(helpArticle.getCatalogId());
                helpArticleCatalog.setSort(helpArticle.getSort() + 1);
                helpArticleCatalogs.add(helpArticleCatalog);
            }
        }
        return helpArticleCatalogs;
    }

    /**
     * editor 加载后端配置项
     *
     * @param response
     * @throws IOException
     */
    public void loadConfig(HttpServletResponse response, HttpServletRequest request) throws IOException {
        String path = this.getClass().getClassLoader().getResource("").getPath() + "/config.json";
        File file = new File(path);
        if (file.exists()) {
            String readFile = readFile(path);
            UEditor uEditor = JSONObject.toJavaObject(JSONObject.parseObject(readFile), UEditor.class);
            uEditor.setImageUrlPrefix("http://" + request.getServerName() + ":" + request.getServerPort()+ request.getContextPath());
            RenderUtil.renderJson(uEditor, response);
        }
    }

    @Override
    public String update(@RequestParam Long id, HttpServletRequest request, Model model) {
        HelpArticle entity = helpArticleService.findOne(id);
        HelpArticleVo helpArticleVo = new HelpArticleVo();
        helpArticleVo.setId(entity.getId());
        helpArticleVo.setCatalogId(entity.getCatalogId());
        HelpArticleCatalog helpArticleCatalog = helpArticleCatalogService.findOne(entity.getCatalogId());
        helpArticleVo.setCatalog(helpArticleCatalog == null ? "" : helpArticleCatalog.getName());
        helpArticleVo.setContent(StringEscapeUtils.unescapeHtml4(entity.getContent()));
        helpArticleVo.setTitle(entity.getTitle());
        model.addAttribute("entity", helpArticleVo);
        return this.getPageFolder() + "/update";
    }

    @Override
    public ApiResponseEntity<Void> update(HttpServletRequest request, HelpArticleForm form, BindingResult result) {

        ValidationUtil.validate(result);
        HelpArticle entity = this.form2Entity(form);
        HelpArticle helpArticle = helpArticleService.findOne(form.getId());
        entity.setAuthor(ShiroUtil.getName());
        entity.setSort(helpArticle.getSort());
        helpArticleService.update(entity);
        return ApiResponseEntity.buildOK();
    }

    /**
     * 富文本编辑器文件上传功能
     *
     * @param response
     * @param request
     * @param filePath
     * @throws IOException
     */
    public void ImageUpload(HttpServletResponse response, HttpServletRequest request, String filePath) throws IOException {
        String basePath = configService.getFileFolderPath();
        UEditorImageUpload uEditorImageUpload = new UEditorImageUpload();
        MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
        Iterator<String> iter = multiRequest.getFileNames();
        while (iter.hasNext()) {
            List<MultipartFile> fileRows = multiRequest
                    .getFiles(iter.next().toString());
            if (fileRows != null && fileRows.size() != 0) {
                if (fileRows.get(0) != null) {
                    String imgPath = filePath + "/" + UuidUtil.getUUID() + "." + fileRows.get(0).getOriginalFilename().substring(fileRows.get(0).getOriginalFilename().lastIndexOf(".") + 1);
                    org.apache.commons.io.FileUtils.copyInputStreamToFile(fileRows.get(0).getInputStream(), new File(basePath + imgPath));
                    uEditorImageUpload.setOriginal(fileRows.get(0).getOriginalFilename());
                    uEditorImageUpload.setTitle(fileRows.get(0).getOriginalFilename());
                    uEditorImageUpload.setSize(fileRows.get(0).getSize());
                    uEditorImageUpload.setState("SUCCESS");
                    uEditorImageUpload.setType("." + fileRows.get(0).getOriginalFilename().substring(fileRows.get(0).getOriginalFilename().lastIndexOf(".") + 1));
                    uEditorImageUpload.setUrl(OtherApi.FILE_PATH + "?path=" + imgPath);
                }
            }
        }
        RenderUtil.renderJson(uEditorImageUpload, response);
    }

    @Override
    public ApiResponseEntity create(HttpServletRequest request, @Valid @ApiParam("创建资源表单") HelpArticleForm form, BindingResult result) {
        ValidationUtil.validate(result);
        HelpArticle entity = this.form2Entity(form);
        entity.setAuthor(ShiroUtil.getName());
        Integer maxSort = helpArticleMapper.findMaxSort(entity.getCatalogId());
        entity.setSort(maxSort == null ? 0 : ++maxSort);
        Long id = helpArticleService.create(entity);
        return ApiResponseEntity.buildOK().setBody(id);
    }


    @Override
    protected void entity2VoDiff(HelpArticle entity, HelpArticleVo vo) {
        Long catalogId = entity.getCatalogId();
        HelpArticleCatalog helpArticleCatalog = helpArticleCatalogService.findOne(catalogId);
        vo.setCatalog(helpArticleCatalog == null ? "" : helpArticleCatalog.getName());
        vo.setContent(StringEscapeUtils.unescapeHtml4(entity.getContent()));
        super.entity2VoDiff(entity, vo);
    }

    public String readFile(String path) throws IOException {

        StringBuilder builder = new StringBuilder();

        try {

            InputStreamReader reader = new InputStreamReader(new FileInputStream(path), "UTF-8");
            BufferedReader bfReader = new BufferedReader(reader);

            String tmpContent = null;

            while ((tmpContent = bfReader.readLine()) != null) {
                builder.append(tmpContent);
            }

            bfReader.close();

        } catch (UnsupportedEncodingException e) {
            // 忽略
        }

        return filter(builder.toString());
    }

    // 过滤输入字符串, 剔除多行注释以及替换掉反斜杠
    public static String filter(String input) {
        return input.replaceAll("/\\*[\\s\\S]*?\\*/", "");
    }
}
